package com.itheima.dao.impl;

import com.itheima.dao.BaseStudentDao;
import com.itheima.domain.Student;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/*
    库管类核心职责:
            1. 接收业务员传过来的业务数据
            2. 对业务数据进行增删改查操作  -- 操作系统数据容器: 数组
            3. 将操作后的结果返回给业务员
    容器升级: 将系统数据仓库由数组容器升级为集合容器
 */
public class StudentDao implements BaseStudentDao {

    private static final Logger LOGGER = LoggerFactory.getLogger(StudentDao.class);

    //1. 创建一个数组容器,作为系统底层的数据仓库
    private static ArrayList<Student> stus = new ArrayList<>();

    //静态代码块: 随着类的加载而执行!只执行一次!
    static {
        //模拟加载数据功能: 将之前系统产生的数据,重新读回内存,存入集合
        System.out.println("--------------------loading----------------");
        reload();
    }

    public boolean addStudent(Student stu) {
        if (getIndex(stu.getId()) != -1)
            return false;

        stus.add(stu);
        //调用存档功能
        reSave();
        return true;
    }

    //库管类中的查看学生功能
    public List<Student> findAllStudent() {
        return stus;
    }

    //库管类中的删除学生功能
    public boolean deleteStudent(String delId) {
        //1. 调用getIndex方法,查找当前id是否存在
        int index = getIndex(delId);

        //2. 根据index来决定是否能够删除成功
        if (index == -1) {
            //说明当前学号不存在,则无法删除,返回false即可
            return false;
        } else {
            //说明当前学号存在,将该学号对应的学生对象从数组中移除,然后返回true
            stus.remove(index);

            //调用存档功能
            reSave();
            return true;
        }
    }

    //库管类中的修改学生功能
    public boolean updateStudent(String updateId, Student newStu) {
        //1. 调用getIndex方法,查找当前id是否存在
        int index = getIndex(updateId);

        //2. 根据index的值来决定能否修改成功
        if (index == -1) {
            //说明学号不存在,则返回false,表示修改失败
            return false;
        } else {
            //说明学号存在,直接将index记录的索引位置用newStu新的学生对象进行覆盖就达到了修改效果
            stus.set(index, newStu);
            //调用存档功能
            reSave();
            return true;
        }
    }

    //封装一个方法: 根据学号查找对应的人在容器中的索引位置
    public int getIndex(String id) {
        //1. 标记位: 先假设要查找的学号不存在
        int index = -1;
        //2. 遍历容器
        for (int i = 0; i < stus.size(); i++) {
            //取出数组中每一个索引位置的元素
            Student stu = stus.get(i);

            //判断当前索引位置的元素的学号与要查找的学号是否相同
            if (stu != null && stu.getId().equals(id)) {
                index = i;      //相同则记录当前学生对象的索引位置
                break;
            }
        }

        //3. 返回index
        return index;
    }

    //封装一个方法: 进行数据持久化(将系统中的数据写到文件保存起来)!   -- 基于序列化流实现
    public void reSave(){
        try{
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\IdeaProjects\\StudentManger-CS\\server\\stu.txt"));

            //2. 直接将集合对象写到文件
            oos.writeObject(stus);

            //3. 关流,释放资源
            oos.close();
        }catch (Exception e){
            //e.printStackTrace();
            LOGGER.error("序列化流时,出现异常:" + e.getMessage());
        }
    }

    //封装一个方法: 进行数据加载(将文件中的数据加载进内存并解析成学生对象,并装载进集合)!   -- 基于反序列化流实现
    public static void reload(){
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\IdeaProjects\\StudentManger-CS\\server\\stu.txt"));
           //2. 将文件中的集合对象读回内存
            stus = (ArrayList<Student>) ois.readObject();
            ois.close();
        }catch (Exception e){
            //e.printStackTrace();
            LOGGER.error("反序列化流时,出现异常:" + e.getMessage());
        }
    }
}
